package javasec.contempt.visuals;

import javasec.contempt.data.SeedConnection;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;


public class TargetsVisual extends EditorPart
{
	public static String ID = "javasec.contempt.visuals.TargetsVisual";
	//private Text entry;
	String tableName;
	private SeedConnection seedConnection=null;
	private ExpandBar expandBar=null;
	private Display display=null;
	
	public TargetsVisual()
	{
		// TODO Auto-generated constructor stub
	}

	public void doSave(IProgressMonitor monitor)
	{
		// TODO Auto-generated method stub

	}

	public void doSaveAs()
	{
		// TODO Auto-generated method stub

	}

	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException
	{
		System.out.println("new database editor init()ed");
		// TODO Auto-generated method stub
		setSite(site);
		setInput(input);
		
		System.out.println("get the database name!");
		tableName=input.getName();
		seedConnection=((VisualInput)input).seedConnection;
		setPartName(seedConnection.name+" targets");
	}

	public boolean isDirty()
	{
		// TODO Auto-generated method stub
		return false;
	}

	public boolean isSaveAsAllowed()
	{
		// TODO Auto-generated method stub
		return false;
	}
	
	public void createPartControl(Composite parent)
	{		
		// save display for async exec later
		display=Display.getCurrent();
		
		// create the table
		expandBar = new ExpandBar(parent,SWT.V_SCROLL);
		
		try
		{
			Object[][] targets=seedConnection.dataSeed.selectAll("TARGET");
			
			for(Object[] target:targets)
			{
				addTarget(target);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		// add the notifiers
		seedConnection.notifier.subscribe("data.newRow.TARGET",this,"addTarget");
		seedConnection.notifier.subscribe("data.updatedField.TARGET",this,"targetUpdated");
	}

	public void addTarget(Object o) // called when a new target is added to the db
	{
		Object[] target=null;
		if(o instanceof Object[])target=(Object[])o;
		else return;
		
		final String targetID=target[0].toString();
		//final String targetTime=target[1].toString();
		final String targetName=target[2].toString();
		final String targetStatus=target[3].toString();
		final String targetNotes=target[4].toString();
		
		// run this in the UI thread
		display.syncExec(new Runnable()
		{
			public void run()
			{
				final ExpandItem expandItem=new ExpandItem(expandBar,SWT.NONE);
				final Text text=new Text(expandBar,SWT.MULTI|SWT.WRAP|SWT.BORDER);
				expandItem.setText(targetName+"   ("+targetStatus+")   ["+targetID+"]");
				text.setText(targetNotes);
				text.setLayoutData(new GridData(GridData.FILL_BOTH));
				expandItem.setHeight(text.computeSize(SWT.DEFAULT, SWT.DEFAULT).y+3);
				expandItem.setControl(text);
				expandItem.setExpanded(true);
				
				// keep resizing text area while typing
				text.addModifyListener(new ModifyListener()
				{
					public void modifyText(ModifyEvent e)
					{
						expandItem.setHeight(text.computeSize(SWT.DEFAULT, SWT.DEFAULT).y+3);
					}					
				});
				
				// once edited, make sure everyone gets an update of the notes
				text.addFocusListener(new FocusListener()
				{
					public void focusGained(FocusEvent e){}
					public void focusLost(FocusEvent e)
					{
						String notes=text.getText();
						try
						{
							seedConnection.dataSeed.updateField("TARGET",new Integer(targetID),"NOTES",(Object)notes);
						}
						catch(Exception e2)
						{
							return;
						}
					}					
				});
			}
		});
	}
	
	// this will be in the form of <id, fieldname, value>
	public void targetUpdated(Object o)
	{	
		try
		{
			Object[] update=(Object[])o;
			if(update.length!=3)return;
			
			final String id=update[0].toString();
			final String fieldName=update[1].toString();
			final String value=update[2].toString();
			
			display.asyncExec(new Runnable()
			{
				public void run()
				{
					for(ExpandItem item:expandBar.getItems())
					{
						String itemText=item.getText();
						String targetID=itemText.substring(itemText.lastIndexOf("[")+1,itemText.lastIndexOf("]"));
						
						if(targetID.equals(id))
						{
							if(fieldName.equals("STATUS"))
							{
								String targetName=itemText.substring(0,itemText.lastIndexOf("   ("));
								item.setText(targetName+"   ("+value+")   ["+id+"]");
								return;
							}
							if(fieldName.equals("NOTES"))
							{
								Text text=(Text)item.getControl();
								text.setText(value);
								return;
							}
						}
						else System.out.println(targetID+" is not "+id);
					}
					System.out.println("dag, the compare didn't work");
				}
			});		
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	
	}
	
	public void setFocus()
	{
	}
}
